package com.oyjd.fw.log.service.impl;

import java.io.BufferedInputStream;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.UUID;

import javax.servlet.http.HttpServletResponse;

import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.oyjd.fw.log.service.LogService;

/**
 * 日志Service实现
 * 
 * @author 欧建东
 * @version 1.0
 */
@Component
@Transactional
public class LogServiceImpl implements LogService {

	private static final String EXPATH = File.separator + "WEB-INF" + File.separator + "logs";
	private static Map<String, FileVO> map = new HashMap<String, FileVO>();

	/**
	 * 获得下载列表
	 * 
	 * @param root
	 *            服务器根路径
	 * @param row
	 *            行模板
	 * @return 固定格式html表格内容
	 */
	public String getList(String root, String row) {
		String path = root + EXPATH;
		File f = new File(path);
		map.clear();
		List<FileVO> debug = new ArrayList<FileVO>();
		List<FileVO> warn = new ArrayList<FileVO>();
		List<FileVO> info = new ArrayList<FileVO>();
		List<FileVO> error = new ArrayList<FileVO>();
		// map
		if (f.exists() && f.isDirectory()) {
			for (File fs : f.listFiles()) {
				String uuid = UUID.randomUUID().toString();
				FileVO vo = new FileVO();
				vo.setKey(uuid);
				vo.setPath(fs.getPath());
				vo.setName(new File(fs.getPath()).getName());
				map.put(uuid, vo);
				if (vo.getName().startsWith("debug")) {
					debug.add(vo);
				} else if (vo.getName().startsWith("warn")) {
					warn.add(vo);
				} else if (vo.getName().startsWith("info")) {
					info.add(vo);
				} else if (vo.getName().startsWith("error")) {
					error.add(vo);
				}

			}
		}
		// 排序
		Collections.sort(debug, new MyComparator());
		Collections.sort(warn, new MyComparator());
		Collections.sort(info, new MyComparator());
		Collections.sort(error, new MyComparator());
		if (debug.size() > 0) {
			debug.add(0, debug.get(debug.size() - 1));
			debug.remove(debug.size() - 1);
		}
		if (warn.size() > 0) {
			warn.add(0, warn.get(warn.size() - 1));
			warn.remove(warn.size() - 1);
		}
		if (info.size() > 0) {
			info.add(0, info.get(info.size() - 1));
			info.remove(info.size() - 1);
		}
		if (error.size() > 0) {
			error.add(0, error.get(error.size() - 1));
			error.remove(error.size() - 1);
		}

		// 组合
		StringBuffer sb = new StringBuffer();
		int rows = debug.size();
		if (warn.size() > rows) {
			rows = warn.size();
		}
		if (info.size() > rows) {
			rows = info.size();
		}
		if (error.size() > rows) {
			rows = error.size();
		}
		for (int i = 0; i < rows; i++) {
			sb.append("<tr>");
			dealFileVO(error, i, sb, row);			
			dealFileVO(warn, i, sb, row);
			dealFileVO(info, i, sb, row);
			dealFileVO(debug, i, sb, row);
			sb.append("</tr>\r\n");
		}
		return sb.toString();
	}

	/**
	 * 输出下载文件
	 * 
	 * @param id
	 *            动态key
	 * @param response
	 *            回应对象
	 */
	public void downLog(String id, HttpServletResponse response) {
		try {
			if (!map.containsKey(id))
				return;

			String path = map.get(id).getPath();

			// path是指欲下载的文件的路径。
			File file = new File(path);
			if (!file.exists())
				return;
			// 取得文件名。
			String fileName = file.getName();

			// 以流的形式下载文件。
			InputStream fis = new BufferedInputStream(new FileInputStream(path));
			byte[] buffer = new byte[fis.available()];
			fis.read(buffer);
			fis.close();

			// 清空response
			response.reset();
			// 设置response的Header
			response.addHeader("Content-Disposition", "attachment;filename=" + new String(fileName.getBytes()));
			response.setContentType("application/octet-stream");
			OutputStream toClient = new BufferedOutputStream(response.getOutputStream());
			toClient.write(buffer);
			toClient.flush();
			toClient.close();
		} catch (IOException ex) {
			ex.printStackTrace();
		}
	}

	/**
	 * 清除日志
	 * 
	 * @param root
	 *            服务器根路径
	 */
	public void deleteLogs(String root) {
		String path = root + EXPATH;
		File f = new File(path);
		map.clear();
		if (f.exists() && f.isDirectory()) {
			for (File fs : f.listFiles()) {
				fs.delete();
			}
		}
	}

	/**
	 * 内部私有排序器
	 * 
	 * @author 欧建东
	 * @version 1.0
	 * 
	 */
	private class MyComparator implements Comparator<FileVO> {
		public int compare(FileVO o1, FileVO o2) {
			return o2.getName().compareTo(o1.getName());
		}

	};

	/**
	 * 组装一个FileVO
	 * 
	 * @param list
	 * @param pos
	 * @param sb
	 */
	private void dealFileVO(List<FileVO> list, int pos, StringBuffer sb, String row) {
		if (pos < list.size()) {
			FileVO vo = list.get(pos);
			sb.append(MessageFormat.format(row, vo.getKey(), vo.getName()));
		} else {
			sb.append("<td width='25%'>&nbsp;</td>");
		}
	}

	/**
	 * 统一用户管理服务日志文件映射对象
	 * 
	 * @author 欧建东
	 * @version 1.0
	 */
	private class FileVO {
		private String key; // 动态key
		private String name;// 文件名
		private String path;// 文件全路径

		public String getKey() {
			return key;
		}

		public void setKey(String key) {
			this.key = key;
		}

		public String getName() {
			return name;
		}

		public void setName(String name) {
			this.name = name;
		}

		public String getPath() {
			return path;
		}

		public void setPath(String path) {
			this.path = path;
		}

	}
}
